package cc.admin.common.db.util;

import cc.admin.common.db.table.entity.DbColumnType;
import com.google.common.base.Strings;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;

import java.util.List;
/**
 * @author: ZhangHouYing
 * @date: 2018-06-24
 */
public class TypeConvertUtil  implements TemplateMethodModelEx {

	@Override
	public Object exec(List args) throws TemplateModelException {
		String distType = "";
		if (args.size() != 2) {
			throw new TemplateModelException("Wrong arguments");
		}
		DbColumnType dbColumnType = (DbColumnType)((freemarker.ext.beans.StringModel) args.get(0)).getWrappedObject();
		String sourceType = dbColumnType.toString();
		String db = ((freemarker.template.SimpleScalar) args.get(1)).getAsString();
		switch(db){
			case "mysql" :
				distType = convertMysqlType(sourceType);
				break;
			case "hive" :
				distType = convertHiveType(sourceType);
				break;
			case "oracle" :
				distType = convertOracleType(sourceType);
				break;
			case "sqlServer":
				distType = convertSqlServerType(sourceType);
				break;
			default :
				throw new RuntimeException("不支持的数据库类型");
		}
		return distType;
	}

	private String convertSqlServerType(String sourceType) {
		return convertMysqlType(sourceType);
	}

	/**
	 * 字段类型转换
	 * @param sourceType VARCHAR,TEXT,DATETIME,TIME,INT,LONG,DOUBLE,NUMBER,FLOAT,TIMESTAMP;
	 * @return
	 */
	private String convertHiveType(String sourceType) {
		String distType = "";
		switch(sourceType){
			case "BLOB" :
			case "VARCHAR" :
			case "TEXT" :
				distType = "string";
				break;
			case "INT" :
				distType = "int";
				break;
			case "LONG" :
				distType = "bigint";
				break;
			case "DOUBLE" :
				distType = "double";
				break;
			case "FLOAT" :
				distType = "float";
				break;
			case "NUMBER" :
				distType = "decimal";
				break;
			case "TIMESTAMP" :
				distType = "timestamp";
				break;
			case "DATE" :
			case "DATETIME" :
				distType = "date";
				break;
			case "TIME" :
				distType = "date";
				break;
			default :
				throw new RuntimeException(Strings.lenientFormat("不支持的字段类型[%s]",sourceType));
		}
		return distType;
	}

	/**
	 * 字段类型转换
	 * @param sourceType VARCHAR,TEXT,DATETIME,TIME,INT,LONG,DOUBLE,NUMBER,FLOAT,TIMESTAMP;
	 * @return
	 */
	private String convertOracleType(String sourceType) {
		String distType = "";
		switch(sourceType){
			case "BLOB" :
				distType = "blob";
				break;
			case "VARCHAR" :
				distType = "varchar2";
				break;
			case "TEXT" :
				distType = "clob";
				break;
			case "INT" :
				distType = "integer";
				break;
			case "LONG" :
				distType = "long";
				break;
			case "DOUBLE" :
			case "FLOAT" :
				distType = "number";
				break;
			case "NUMBER" :
				distType = "number";
				break;
			case "TIMESTAMP" :
				distType = "timestamp";
				break;
			case "DATE" :
				distType = "date";
				break;
			case "DATETIME" :
				distType = "timestamp";
				break;
			case "TIME" :
				distType = "date";
				break;
			default :
				throw new RuntimeException(Strings.lenientFormat("不支持的字段类型[%s]",sourceType));
		}
		return distType;
	}

	/**
	 * 字段类型转换
	 * @param sourceType VARCHAR,TEXT,DATETIME,TIME,INT,LONG,DOUBLE,NUMBER,FLOAT,TIMESTAMP;
	 * @return
	 */
	private String convertMysqlType(String sourceType) {
		String distType = "";
		switch(sourceType){
			case "BLOB" :
				distType = "blob";
				break;
			case "VARCHAR" :
				distType = "varchar";
				break;
			case "TEXT" :
				distType = "text";
				break;
			case "INT" :
				distType = "int";
				break;
			case "LONG" :
				distType = "bigint";
				break;
			case "DOUBLE" :
				distType = "double";
				break;
			case "FLOAT" :
				distType = "float";
				break;
			case "NUMBER" :
				distType = "numeric";
				break;
			case "TIMESTAMP" :
				distType = "timestamp";
				break;
			case "DATE" :
				distType = "date";
				break;
			case "DATETIME" :
				distType = "datetime";
				break;
			case "TIME" :
				distType = "time";
				break;
			default :
				throw new RuntimeException(Strings.lenientFormat("不支持的字段类型[%s]",sourceType));
		}
		return distType;
	}
}
